package com.kordar.auth;

import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;

import java.util.Set;

@Slf4j
public class CustomRealm extends AuthorizingRealm {

    AuthService authService;

    public void setAuthService(AuthService authService) {
        this.authService = authService;
    }

    {
        super.setName("customRealm");
    }

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        String username = (String) principalCollection.getPrimaryPrincipal();
        Admin admin = authService.findOneByUsername(username);
        if (admin == null) {
            return null;
        }
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        simpleAuthorizationInfo.setStringPermissions(authService.findPermissionsByUser(admin));
        simpleAuthorizationInfo.setRoles(authService.findRolesByUser(admin));
        return simpleAuthorizationInfo;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        // 从主体传递的认证信息中，获得用户名
        String username = (String) authenticationToken.getPrincipal();
        // 通过用户名到数据库中获取凭证
        Admin admin = authService.findOneByUsername(username);
        if (admin == null) { return null; }
        log.debug("Authentication:" + admin.toString());
        SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(admin.getUsername(), admin.getPassword(), "customRealm");
        authenticationInfo.setCredentialsSalt(ByteSource.Util.bytes(admin.getSalt()));
        return authenticationInfo;
    }
}
